package org.meb.lotrlcg.db.dao;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.meb.lotrlcg.db.model.EncounterSetBase;
import org.meb.lotrlcg.db.model.EncounterSetBase_;
import org.meb.lotrlcg.db.model.ScenEnstLink;
import org.meb.lotrlcg.db.model.ScenEnstLink_;
import org.meb.lotrlcg.db.model.ScenarioBase;
import org.meb.lotrlcg.db.model.ScenarioBase_;

public class ScenEnstLinkDao {

	private EntityManager em;

	public ScenEnstLinkDao(EntityManager em) {
		this.em = em;
	}

	private TypedQuery<ScenEnstLink> createQuery(ScenEnstLink example) {
		CriteriaBuilder cb = em.getCriteriaBuilder();
		CriteriaQuery<ScenEnstLink> cq = cb.createQuery(ScenEnstLink.class);
		Root<ScenEnstLink> root = cq.from(ScenEnstLink.class);
		cq.select(root);

		List<Predicate> predicates = new ArrayList<Predicate>(3);

		EncounterSetBase esb = example.getEncounterSetBase();
		if (esb != null) {
			String enstTechName = esb.getTechName();
			if (StringUtils.isNotBlank(enstTechName)) {
				Join<ScenEnstLink, EncounterSetBase> enst = root
						.join(ScenEnstLink_.encounterSetBase);
				predicates.add(cb.equal(cb.lower(enst.get(EncounterSetBase_.techName)),
						enstTechName.toLowerCase()));
			}
		}

		ScenarioBase sb = example.getScenarioBase();
		if (sb != null) {
			String scenTechName = sb.getTechName();
			if (StringUtils.isNotBlank(scenTechName)) {
				Join<ScenEnstLink, ScenarioBase> scen = root.join(ScenEnstLink_.scenarioBase);
				predicates.add(cb.equal(cb.lower(scen.get(ScenarioBase_.techName)),
						scenTechName.toLowerCase()));
			}
		}

		if (predicates.size() > 0) {
			cq.where(predicates.toArray(new Predicate[predicates.size()]));
		}

		return em.createQuery(cq);
	}

	public List<ScenEnstLink> find(ScenEnstLink example) {
		return createQuery(example).getResultList();
	}

	public ScenEnstLink findUnique(ScenEnstLink example) {
		ScenEnstLink csl;
		try {
			csl = createQuery(example).getSingleResult();
		} catch (NoResultException e) {
			csl = null;
		}
		return csl;
	}

	public ScenEnstLink findUnique(Long id) {
		return em.find(ScenEnstLink.class, id);
	}
}
